const Student = require('../model/studentModel');
const { sm2, sm3 } = require('sm-crypto');
const { output } = require("../common/index");
const Snowflake = require('node-snowflake').Snowflake;
const xlsx = require('xlsx');
const path = require('path');

// 获取学生列表
const getStudentList = async (req, res) => {
    try {
        const { keyword } = req.query;
        let query = {};

        if (keyword) {
            // 使用正则表达式进行模糊查询，匹配学号或姓名
            query = {
                $or: [
                    { account: new RegExp(keyword, 'i') },  // i 表示不区分大小写
                    { name: new RegExp(keyword, 'i') }
                ]
            };
        }

        const students = await Student.find(query)
            .select('-password')  // 排除密码字段
            .sort({ createTime: -1 });  // 按创建时间倒序排序

        output(res, {
            code: 0,
            data: students,
            message: '获取成功'
        });
    } catch (error) {
        output(res, {
            code: 1,
            message: error.message || '获���学生列表失败',
            data: null
        });
    }
};

// 创建学生
const createStudent = async (req, res) => {
    const studentData = req.body;

    // 使用SM3加密密码
    studentData.password = sm3(studentData.password);

    // 生成雪花ID
    studentData.id = Snowflake.nextId();

    try {
        const student = new Student(studentData);
        await student.save();
        output(res, {
            code: 0,
            message: '创建成功'
        });
    } catch (error) {
        output(res, {
            code: 1,
            message: '创建失败'
        });
    }
};

// 更新学生信息
const updateStudent = async (req, res) => {
    try {
        // 检查学号是否与其他学生重复
        const existStudent = await Student.findOne({
            account: req.body.account,
            id: { $ne: req.params.id }  // 使用雪花ID而不是_id
        });

        if (existStudent) {
            return res.json({
                code: 1,
                message: '该学号已被其他学生使用',
                data: null
            });
        }

        // 使用雪花ID查找并更新
        const student = await Student.findOneAndUpdate(
            { id: req.params.id },  // 使用雪花ID查找
            {
                ...req.body,
                updateTime: new Date()
            },
            { new: true }
        );

        if (!student) {
            return res.json({
                code: 1,
                message: '学生不存在',
                data: null
            });
        }

        res.json({
            code: 0,
            message: '更新成功',
            data: student
        });
    } catch (error) {
        res.json({
            code: 1,
            message: error.message || '更新学生失败',
            data: null
        });
    }
};

// 删除学生
const deleteStudent = async (req, res) => {
    try {
        // 使用雪花ID查找并删除
        const student = await Student.findOneAndDelete({ id: req.params.id });

        if (!student) {
            return res.json({
                code: 1,
                message: '学生不存在',
                data: null
            });
        }

        res.json({
            code: 0,
            message: '删除成功',
            data: null
        });
    } catch (error) {
        res.json({
            code: 1,
            message: error.message || '删除失败',
            data: null
        });
    }
};

// 添加学生
const addStudent = async (req, res) => {
    try {
        // 检查学号是否已存在
        const existStudent = await Student.findOne({ account: req.body.account });
        if (existStudent) {
            return res.json({
                code: 1,
                message: '该学号已存在',  // 明确的错误信息
                data: null
            });
        }

        const student = new Student(req.body);
        await student.save();

        res.json({
            code: 0,
            message: '添加成功',
            data: student
        });
    } catch (error) {
        res.json({
            code: 1,
            message: error.message || '添加学生失败',  // 使用具体的错误信息
            data: null
        });
    }
};

// 导出学生数据
const exportStudents = async (req, res) => {
    try {
        // 获取所有学生数据（排除密码字段）
        const students = await Student.find()
            .select('-password -_id')
            .lean();  // 使用 lean() 获取纯 JavaScript 对象

        // 转换数据格式
        const exportData = students.map(student => ({
            '学号': student.account || '',
            '姓名': student.name || '',
            '学院': student.college || '',
            '专业': student.major || '',
            '班级': student.className || '',
            '性别': student.gender === 1 ? '男' : '女',
            '手机号': student.phone || '',
            '身份证': student.idCard || ''
        }));

        // 创建工作簿和工作表
        const wb = xlsx.utils.book_new();
        const ws = xlsx.utils.json_to_sheet(exportData, {
            header: ['学号', '姓名', '学院', '专业', '班级', '性别', '手机号', '身份证']
        });

        // 设置列宽
        const colWidth = [
            { wch: 15 }, // 学号
            { wch: 10 }, // 姓名
            { wch: 20 }, // 学院
            { wch: 20 }, // 专业
            { wch: 15 }, // 班级
            { wch: 8 },  // 性别
            { wch: 15 }, // 手机号
            { wch: 20 }  // 身份证
        ];
        ws['!cols'] = colWidth;

        // 添加工作表到工作簿
        xlsx.utils.book_append_sheet(wb, ws, '学生信息');

        // 生成 buffer
        const buffer = xlsx.write(wb, {
            type: 'buffer',
            bookType: 'xlsx'
        });

        // 设置响应头
        res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        res.setHeader('Content-Disposition', 'attachment; filename=students.xlsx');

        // 发送文件
        res.send(buffer);
    } catch (error) {
        console.error('导出错误:', error);
        output(res, {
            code: 1,
            message: '导出失败: ' + error.message
        });
    }
};

// 导入学生数据
const importStudents = async (req, res) => {
    try {
        if (!req.files || !req.files.file) {
            return output(res, {
                code: 1,
                message: '请上传文件'
            });
        }

        const file = req.files.file;
        const workbook = xlsx.read(file.data);
        const worksheet = workbook.Sheets[workbook.SheetNames[0]];
        const data = xlsx.utils.sheet_to_json(worksheet);

        const results = await Promise.all(data.map(async (row) => {
            try {
                const studentData = {
                    account: row['学号'],
                    name: row['姓名'],
                    password: sm3('123456'), // 默认密码
                    college: row['学院'],
                    major: row['专业'],
                    className: row['班级'],
                    gender: row['性别'] === '男' ? 1 : 2,
                    phone: row['手机号'],
                    idCard: row['身份证'],
                    id: Snowflake.nextId()
                };

                const student = new Student(studentData);
                await student.save();
                return true;
            } catch (error) {
                console.error(`导入失败: ${row['学号']}`, error);
                return false;
            }
        }));

        const successCount = results.filter(Boolean).length;

        output(res, {
            code: 0,
            message: `成功导入 ${successCount}/${data.length} 条数据`
        });
    } catch (error) {
        output(res, {
            code: 1,
            message: '导入失败: ' + error.message
        });
    }
};

// 下载模板
const downloadTemplate = async (req, res) => {
    try {
        const template = [
            {
                '学号': '',
                '姓名': '',
                '学院': '',
                '专业': '',
                '班级': '',
                '性别': '男/女',
                '手机号': '',
                '身份证': ''
            }
        ];

        const wb = xlsx.utils.book_new();
        const ws = xlsx.utils.json_to_sheet(template);
        xlsx.utils.book_append_sheet(wb, ws, '学生信息');

        const buffer = xlsx.write(wb, { type: 'buffer', bookType: 'xlsx' });

        res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        res.setHeader('Content-Disposition', 'attachment; filename=template.xlsx');
        res.send(buffer);
    } catch (error) {
        output(res, {
            code: 1,
            message: '下载模板失败'
        });
    }
};

// 预览导入数据
const previewImport = async (req, res) => {
    try {
        if (!req.files || !req.files.file) {
            return output(res, {
                code: 1,
                message: '请上传文件'
            });
        }

        const file = req.files.file;
        const workbook = xlsx.read(file.data);
        const worksheet = workbook.Sheets[workbook.SheetNames[0]];
        const data = xlsx.utils.sheet_to_json(worksheet);

        // 验证数据
        const validatedData = await Promise.all(data.map(async (row) => {
            const errors = [];

            // 验证必填字段
            if (!row['学号']) errors.push('学号不能为空');
            if (!row['姓名']) errors.push('姓名不能为空');
            if (!row['学院']) errors.push('学院不能为空');
            if (!row['专业']) errors.push('专业不能为空');
            if (!row['班级']) errors.push('班级不能为空');
            if (!row['性别']) errors.push('性别不能为空');

            // 验证学号是否重复
            if (row['学号']) {
                const existStudent = await Student.findOne({ account: row['学号'] });
                if (existStudent) errors.push('学号已存在');
            }

            return {
                account: row['学号'] || '',
                name: row['姓名'] || '',
                college: row['学院'] || '',
                major: row['专业'] || '',
                className: row['班级'] || '',
                gender: row['性别'] === '男' ? 1 : 2,
                phone: row['手机号'] || '',
                idCard: row['身份证'] || '',
                error: errors.length ? errors.join('; ') : ''
            };
        }));

        output(res, {
            code: 0,
            data: validatedData
        });
    } catch (error) {
        output(res, {
            code: 1,
            message: '预览失败: ' + error.message
        });
    }
};

// 确认导入
const confirmImport = async (req, res) => {
    try {
        const { data } = req.body;
        const results = [];
        const errors = [];

        // 使用 for...of 循环顺序处理，而不是 Promise.all
        for (const item of data) {
            try {
                const studentData = {
                    ...item,
                    password: sm3('123456'), // 默认密码
                    id: Snowflake.nextId()
                };

                const student = new Student(studentData);
                await student.save();
                results.push(item.account);
            } catch (error) {
                console.error(`导入失败: ${item.account}`, error);
                errors.push({
                    account: item.account,
                    error: error.message
                });
            }
        }

        output(res, {
            code: 0,
            message: `成功导入 ${results.length}/${data.length} 条数据${errors.length ? '，部分数据导入失败' : ''}`,
            data: {
                success: results,
                errors: errors
            }
        });
    } catch (error) {
        output(res, {
            code: 1,
            message: '导入失败: ' + error.message
        });
    }
};

module.exports = {
    getStudentList,
    createStudent,
    updateStudent,
    deleteStudent,
    addStudent,
    exportStudents,
    importStudents,
    downloadTemplate,
    previewImport,
    confirmImport
};